package com.example.emos.wx.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.example.emos.wx.common.util.R;
import com.example.emos.wx.config.shiro.JwtTokenUtils;
import com.example.emos.wx.config.tencent.TLSSigAPIv2;
import com.example.emos.wx.controller.form.*;
import com.example.emos.wx.db.mapper.TbUserMapper;
import com.example.emos.wx.exception.EmosException;
import com.example.emos.wx.service.UserService;
import io.swagger.annotations.ApiOperation;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName UserController
 * @Description TODO
 * @Author daoketa
 * @Version 1.0
 **/
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private JwtTokenUtils jwtTokenUtils;

    @Value("${emos.jwt.cache-expire}")
    private int cacheExpire;

    @Value("${trtc.appid}")
    private Integer trtcAppid;

    @Value("${trtc.key}")
    private String trtcKey;

    @Value("${trtc.expire}")
    private Integer trtcExpire;

    @PostMapping("/register")
    @ApiOperation("注册新用户")
    public R registerUser(@Valid @RequestBody RegisterForm form){
        Integer userId = userService.registerUser(form.getRegisterCode(), form.getCode(), form.getNickname(), form.getPhoto());
        String token = jwtTokenUtils.createToken(userId);
        saveCacheToken(token,userId);
        Set<String> permission = userService.searchUserPermissions(userId);
        return R.ok("用户注册成功").put("token", token).put("permission", permission);
    }

    /**
     * 用户登录，生成令牌，查询用户权限
     * @author daoketa
     * @param
     *
     */
    @PostMapping("/login")
    @ApiOperation("用户登录")
    public R loginUser(@Valid @RequestBody LoginForm loginForm, @RequestHeader("token") String token){
        Integer userId = 0;

        /** 判断用户是否重复登录，避免多次创建 token */
        if(StrUtil.isNotEmpty(token)){
            /** 验证令牌有效性 */
            try {
                jwtTokenUtils.verifierToken(token);
            }catch (TokenExpiredException e){
                /** 令牌过期 */
                userId = userService.login(loginForm.getCode());
                token = jwtTokenUtils.createToken(userId);
                saveCacheToken(token,userId);
            }
            userId = jwtTokenUtils.getUserId(token);
        }else {
            /** 第一次登录，根据临时授权字符串查找用户 id，创建令牌 */
            userId = userService.login(loginForm.getCode());
            token = jwtTokenUtils.createToken(userId);
            saveCacheToken(token,userId);
        }

        Set<String> permission = userService.searchUserPermissions(userId);
        return R.ok("用户登录成功").put("token", token).put("permission", permission);
    }

    @PostMapping("/insertUser")
    @ApiOperation("添加新用户")
    @RequiresPermissions(value = {"ROOT","EMPLOYEE:INSERT"}, logical = Logical.OR)
    public R insertUser(@Valid @RequestBody InsertUserForm form){
        log.info(form.getRole());

        if(!JSONUtil.isJsonArray(form.getRole())){
            throw new EmosException("角色不是数组格式");
        }
        JSONArray array = JSONUtil.parseArray(form.getRole());
        HashMap param = new HashMap();
        param.put("name", form.getName());
        param.put("sex", form.getSex());
        param.put("tel", form.getTel());
        param.put("email", form.getEmail());
        param.put("hiredate", form.getHiredate());
        param.put("role", form.getRole());
        param.put("deptName", form.getDeptName());
        param.put("status", form.getStatus());
        param.put("createTime", new Date());
        if (array.contains(0)) {
            param.put("root", true);
        } else {
            param.put("root", false);
        }
        userService.insertUser(param);
        return R.ok().put("result","success");
    }

    @GetMapping("/searchUserSummary")
    @ApiOperation("查询用户摘要信息")
    public R searchUserSummary(@RequestHeader("token") String token) {
        int userId = jwtTokenUtils.getUserId(token);
        HashMap map = userService.searchUserSummary(userId);
        return R.ok().put("result", map);
    }

    @PostMapping("/searchUserGroupByDept")
    @ApiOperation("查询员工列表，按照部门分组排列")
    @RequiresPermissions(value = {"ROOT","EMPLOYEE:SELECT"}, logical = Logical.OR)
    public R searchUserGroupByDept(@Valid @RequestBody SearchUserGroupByDeptForm form){
        ArrayList<HashMap> list = userService.searchUserGroupByDept(form.getKeyword());
        return R.ok().put("result", list);
    }

    @PostMapping("/searchMembers")
    @ApiOperation("查询成员")
    @RequiresPermissions(value = {"ROOT", "MEETING:INSERT", "MEETING:UPDATE"}, logical = Logical.OR)
    public R searchMembers(@Valid @RequestBody SearchMembersForm form) {
        if (!JSONUtil.isJsonArray(form.getMembers())) {
            throw new EmosException("members不是JSON数组");
        }
        List param = JSONUtil.parseArray(form.getMembers()).toList(Integer.class);
        ArrayList list = userService.searchMembers(param);
        return R.ok().put("result", list);
    }

    @PostMapping("/searchUserNameAndPhoto")
    @ApiOperation("查询用户姓名和头像")
    @RequiresPermissions(value = {"WORKFLOW:APPROVAL"})
    public R selectUserPhotoAndName(@Valid @RequestBody SearchUserPhotoAndNameForm form) {
        if (!JSONUtil.isJsonArray(form.getIds())) {
            throw new EmosException("参数不是JSON数组");
        }
        List<Integer> param = JSONUtil.parseArray(form.getIds()).toList(Integer.class);
        List<HashMap> list = userService.searchUserNameAndPhoto(param);
        return R.ok().put("result",list);
    }

    @GetMapping("/genUserSig")
    @ApiOperation("生成用户签名")
    public R genUserSig(@RequestHeader("token") String token){
        int id = jwtTokenUtils.getUserId(token);
        TLSSigAPIv2 api = new TLSSigAPIv2(trtcAppid, trtcKey);
        String userSig = api.genUserSig(id+"", trtcExpire);
        return R.ok().put("userSig", userSig).put("id", id);
    }

    @PostMapping("/searchUserInfo")
    @ApiOperation("查询员工数据")
    @RequiresPermissions(value = {"ROOT", "EMPLOYEE:SELECT"}, logical = Logical.OR)
    public R searchUserInfo(@Valid @RequestBody SearchUserInfoForm form) {
        HashMap map = userService.searchUserInfo(form.getUserId());
        return R.ok().put("result", map);
    }

    @GetMapping("/searchUserSelfInfo")
    @ApiOperation("查询自身信息")
    public R searchUserSelfInfo(@RequestHeader("token") String token) {
        int userId = jwtTokenUtils.getUserId(token);
        HashMap map = userService.searchUserInfo(userId);
        return R.ok().put("result", map);
    }

    @PostMapping("/updateUserInfo")
    @ApiOperation("更新用户数据")
    @RequiresPermissions(value = {"ROOT", "EMPLOYEE:UPDATE"}, logical = Logical.OR)
    public R updateUserInfo(@Valid @RequestBody UpdateUserInfoForm form) {
        boolean root = false;
        if (!JSONUtil.isJsonArray(form.getRole())) {
            throw new EmosException("role不是有效的JSON数组");
        } else {
            JSONArray role = JSONUtil.parseArray(form.getRole());
            root = role.contains(0) ? true : false;
        }
        HashMap param = new HashMap();
        param.put("name", form.getName());
        param.put("sex", form.getSex());
        param.put("deptName", form.getDeptName());
        param.put("tel", form.getTel());
        param.put("email", form.getEmail());
        param.put("hiredate", form.getHiredate());
        param.put("role", form.getRole());
        param.put("status", form.getStatus());
        param.put("userId", form.getUserId());
        param.put("root", root);

        int rows = userService.updateUserInfo(param);
        return R.ok().put("result", rows);
    }

    @PostMapping("/deleteUserById")
    @ApiOperation("删除员工记录")
    @RequiresPermissions(value = {"ROOT", "EMPLOYEE:DELETE"}, logical = Logical.OR)
    public R deleteUserById(@Valid @RequestBody DeleteUserByIdForm form) {
        userService.deleteUserById(form.getId());
        return R.ok().put("result", "success");
    }

    @GetMapping("/searchUserContactList")
    @ApiOperation("查询通讯录列表")
    public R searchUserContactList() {
        JSONObject json = userService.searchUserContactList();
        return R.ok().put("result", json);
    }

    public void saveCacheToken(String token, Integer userId){
        redisTemplate.opsForValue().set(token, userId + "", cacheExpire, TimeUnit.DAYS);
    }

}
